package com.cyanite.playlv2api.util;

import com.cyanite.playlv2api.error.PlayLv2ApiCredentialsException;
import com.cyanite.playlv2api.error.PlayLv2ApiException;
import com.cyanite.playlv2api.error.PlayLv2ApiParseException;
import com.cyanite.playlv2api.parsers.json.Parser;
import com.cyanite.playlv2api.types.PlayLv2Type;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Iterator;

@SuppressWarnings("unchecked")
public class JSONUtils {

    /**
     * Takes a parser, a json string, and returns a playlv2 type.
     */
    public static PlayLv2Type consume(Parser<? extends PlayLv2Type> parser, String content)
        throws PlayLv2ApiCredentialsException, PlayLv2ApiParseException, PlayLv2ApiException, IOException {

        try {
            // The v1 API returns the response raw with no wrapper. Depending on the
            // type of API call, the content might be a JSONObject or a JSONArray.
            // Since JSONArray does not derive from JSONObject, we need to check for
            // either of these cases to parse correctly.
            JSONObject json = new JSONObject(content);
            Iterator<String> it = (Iterator<String>)json.keys();
            if (it.hasNext()) {
                String key = (String)it.next();
                if ( key.equals("groups") )  {
                    Object obj = json.get(key);
                    if (obj instanceof JSONArray) {
                        return parser.parse((JSONArray)obj);
                    } else {
                        return parser.parse((JSONObject)obj);
                    }
                }

                if ( !json.getString("error").equals("0") ) {
                    throw new PlayLv2ApiException(json.getString("message"));
                } else {
                    String cont = json.getString("content");
                    if (cont != null && !cont.equals("") && !cont.equals("[]")) {
                        Object obj = json.get("content");
                        JSONObject objArray = (JSONObject)obj;
                        if (objArray.has("list"))  {
                            obj = objArray.get("list");
                            return parser.parse((JSONArray)obj);
                        }  else {
                            return parser.parse((JSONObject)obj);
                        }
                    }
                    return null;
                }
            } else {
                throw new PlayLv2ApiException("Error parsing JSON response, object had no single child key.");
            }

        } catch (JSONException ex) {
            throw new PlayLv2ApiException("Error parsing JSON response: " + ex.getMessage());
        }
    }
}